<?php
require_once('TVB/pms/pdes/action/EpisodeGetAction.class.php');

class EpisodeUpdateAction extends BaseAction 
{
	/**
	 * @isnull false
	 */
	public $id;
	public $programme_id;
	/**
	 * @isnull false
	 * @filter positive_number
	 * @maxLength 9
	 * @label On Air Episode No.
	 */
	public $onair_episode_no;
	public $original_episode_no;

// bug 3979
//	/**
//	 * @maxLength 9
//	 * @label Average Rating
//	 */
//	public $average_rating;
    
	/**
	 * @filter datetime
	 * @label On Air Date/Time
	 */
	public $first_time_onair;
	/**
	 * @isnull false
	 * @filter datetime
	 * @label Publish Date/Time
	 */
	public $publish_datetime;
	/**
	 * @isnull false
	 * @filter datetime
	 * @label Expiry Date/Time
	 */
	public $expire_datetime;
	public $other_language_episodes;
	public $highlighted_cast_roles;
	public $casts;
	public $available_tag_types;
	public $tags;
	#public $folders;
	public $status;
	public $created_at;
	public $created_by;
	public $modified_at;
	public $modified_by;

	public $language_id;
	/**
	 * @maxLength 255
	 * @label Episode Title (Chinese)
	 */
	public $title;
	
	public $description;
	public $description_en;
	
    public $description_short;
    public $description_short_en;
	
	public $editor_message;
	public $editor_message_en;

	//public $tag;
	//public $new_tag;
	//public $role_id;
	public $cast_id;
	public $name_type;
	public $name_last;
	public $name_first;
	public $alphabet;
	/**
	 * @maxLength 255
	 * @label Episode Title (English)
	 */
	public $title_en;
	public $param_role_id;
	public $param_cast_id;
	public $param_name_type;
	public $param_last_name;
	public $param_first_name;
	public $param_alphabet;

	public $vid;
	public $act;

	public $ut;
	public $reset;
	public $from;

    /*
     * for bug 786
     * */
    public $is_folder_update;

	public function execute(){

		if (!is_null($this->reset))
		{
			$this->setData('id', $this->id);
			$this->setData('act', 'edit');
			$this->setData('step', 2);
			$this->setData('from', $this->from);
			return 'reset';
		}

		Model::$dbo['w']->beginTransaction();
		try{
			if (CommonUtils::is_concurrent('episode', $this->id, $this->modified_at))
			{
				$this->init_page_data();
				$this->addError('concurrent', array('0105', 'Concurrent update found!'));
				return 'logic-error';
			}

			if(count($this->_errors) > 0){
				$this->init_page_data();
				return 'filter-error';
			}

			//check date
			if (!is_null($this->expire_datetime))
			{
				if ($this->publish_datetime > $this->expire_datetime)
				{
					$this->init_page_data();
					$this->addError('Publish Date/Time && Expiry Date/Time', array('0033', 'Publish Date/Time && Expiry Date/Time'));
					return 'filter-error';
				}
			}

			//check programme and on air episode no
			$check_exists = episode::getEpisodeID($this->programme_id, $this->onair_episode_no);
			if ($check_exists != '' && $check_exists != $this->id)
			{
				$this->addError('Programme or Episode', array('0102', 'Programme or Episode'));
				$this->init_page_data();
				return 'logic-error';
			}

			# change_log
			$this->change_log = array();
			$cast_id   = $this->handle_cast_main();
			$this->update_episode($cast_id);
			$this->update_episode_language();
            $this->update_multiple_language($this->id);
			# save change_log
			array_walk($this->change_log,'change_log::updateOne');
            
            $primary_key = array(
                'episode_id'    => $this->id
            );
            $fields = array(
                'title',
                'description',
                'description_short',
                'editor_message'
            );
            CommonUtils::filterC2A0('episode-language', $primary_key, $fields);

			Model::$dbo['w']->commit();

            if ($this->is_folder_update) {
                $this->setData('act', 'edit');
                $this->setData('step', '2');
                $this->setData('id', $this->id);

                return 'folder';
            }
            else if (is_null($this->param_cast_id) && is_null($this->vid))
			{
				if ($this->from == 'task') 
				{
					return 'task';
				}
				else
				{
					$this->setData('type','episode');
					return 'succ';
				}
			}
			elseif ($this->vid)
			{
				$this->setData('type','chapter_marking');
				$this->setData('act', 'edit');
				$this->setData('vid', $this->vid);
				$this->setData('from', 'episode');
				return 'video';
			}
			else
			{
				$this->setData('id', $cast_id);
				$act = ($this->param_cast_id < 0) ? 'add' : 'edit';
				$this->setData('act', $act);
				$this->setData('from', 'episode');
				$this->setData('episode_id', $this->id);
				$this->setData('step', 2);
				return 'cast';
			}
		}
		catch(Exception $e)
		{
			error_log("Update Episode Fails: $this->id");
			error_log("Request: " . var_export($this, 1));

			Model::$dbo['w']->rollBack();

			return 'system-error';
		}
	}    

	/**
	 * update episode
	 */
	private function update_episode($cast_id)
	{
		$episode = new episode();
		$episode = $episode->get($this->id);
		Model::diff($episode, $this);
		$episode->modified_at = date("Y-m-d H:i:s", $_SERVER['REQUEST_TIME']);
		$episode->modified_by = CommonUtils::get_user();
		//$episode->tags = $this->add_tag();
		$episode->first_time_onair = $this->first_time_onair;
		$episode->expire_datetime =  $this->expire_datetime;
		$episode->publish_datetime = $this->publish_datetime;
		$episode->casts = $this->add_cast_field($cast_id);

		$update_id = Model::$dbo['w']->save($episode);
		if ($update_id > 0)
		{
			$this->change_log[] = array(
				'type' => 'episode',
				'keys' => array('id'=>$this->id),
				'is_active'=>1,
				'is_publish'=> 0,
				'episode_id'=>array($this->id),
			);
			$this->addInfo("episode:".AC::LOG_OP_UPDATE.":".$this->id, "update episode success", json_encode($episode));
		}
		else
		{
			$this->addError("episode:".AC::LOG_OP_UPDATE.":".$this->id, "update episode failed", json_encode($episode));
		}
	}

	/**
	 * update episode language
	 */
	private function update_episode_language()
	{
		$episode_language = new episode_language();
		$lang_id = language::getLanguageID(AC::DEFAULT_LANGUAGE);
		$episode_language = $episode_language->getLangEpisodeByID($this->id, $lang_id);
		Model::diff($episode_language, $this);
		$episode_language->title = is_null($this->title) ? '' : trim($this->title);
        $episode_language->description = is_null($this->description) ? '' : $this->description;
        $episode_language->description_short = is_null($this->description_short) ? '' : $this->description_short;
        $update_id = Model::$dbo['w']->save_by_fields($episode_language, array('episode_id','language_id'));
		if ($update_id)
		{
			$this->change_log[] = array(
				'type' => 'episode-language',
				'keys' => array('episode_id'=>$this->id,'language_id'=>$lang_id),
				'is_active'=>1,
				'is_publish'=> 0,
				'episode_id'=>array($this->id),
			);
			$this->addInfo("episode-language:".AC::LOG_OP_UPDATE.":".$this->id, "update episode language success", json_encode($episode_language));
		}
		else
		{
			$this->addError("episode-language:".AC::LOG_OP_UPDATE.":".$this->id, "update episode language failed", json_encode($episode_language));
		}
	}

	/**
	 * update episode multiple language
	 */
	private function update_multiple_language($episode_id)
	{
		$this->editor_message_en = is_null($this->editor_message_en) ? '' : $this->editor_message_en;
		$lang_id = language::getLanguageID(AC::LANGUAGE_EN);
		
		$episode_language = new episode_language();
		$episode_exists = $episode_language->getLangEpisodeByID($episode_id, $lang_id);
		if ($episode_exists) {
			Model::diff($episode_exists, $this);
			$episode_exists->title = is_null($this->title_en) ? '' : trim($this->title_en);
		    $episode_exists->description = is_null($this->description_en) ? '' : $this->description_en;
		    $episode_exists->description_short = is_null($this->description_short_en) ? '' : $this->description_short_en;
			$episode_exists->language_id = language::getLanguageID(AC::LANGUAGE_EN);
			$episode_exists->editor_message = $this->editor_message_en;
		} else {
			$episode_language->set($this);
			$episode_language->language_id = language::getLanguageID(AC::LANGUAGE_EN);
			$episode_language->episode_id = $episode_id;
			$episode_language->title = is_null($this->title_en) ? '' : trim($this->title_en);
    	    $episode_language->description = is_null($this->description_en) ? '' : $this->description_en;
		    $episode_language->description_short = is_null($this->description_short_en) ? '' : $this->description_short_en;
			$episode_language->editor_message = $this->editor_message_en;
		}

		$ret = ($episode_exists) ? Model::$dbo['w']->save_by_fields($episode_exists, array('episode_id','language_id')) : Model::$dbo['w']->save($episode_language);
		if ($ret >= 0)
		{
			$this->change_log[] = array(
				'type' => 'episode-language',
				'keys' => array('episode_id'=>$this->id,'language_id'=>$lang_id),
				'is_active'=>1,
				'is_publish'=> 0,
				'episode_id'=>array($this->id),
			);
			$this->addInfo("episode-language:".AC::LOG_OP_UPDATE.":".$episode_id, "update episode language success", json_encode($episode_language));
		}
		else
		{
			$this->addError("episode-language:".AC::LOG_OP_UPDATE.":".$episode_id, "update episode language error", json_encode($episode_language));
		}
	}

	/**
	 * handle cast array
	 */
	/*
	private function add_cast_field($cast_id)
	{
		if ($cast_id > 0)
		{
			$new_cmp_array = array("name_type"=>$this->param_name_type,"last_name"=>trim($this->param_last_name),"first_name"=>trim($this->param_first_name),"alphabet"=>(int)$this->param_alphabet);
		}
		else
		{
			$new_cmp_array = false;
		}

		$cast_arr = array();
		$len = count($this->role_id);
		for ($i=0; $i<$len; $i++)
		{
			if (empty($this->name_first[$i])) continue;
		
			$role_id = $this->role_id[$i];
			$old_cmp_array = array("name_type"=>$this->name_type[$i],"last_name"=>trim($this->name_last[$i]),"first_name"=>trim($this->name_first[$i]), "alphabet"=>$this->alphabet[$i]);
			
			if ($new_cmp_array)
			{
				$cmp_result = array_diff_assoc($new_cmp_array, $old_cmp_array);
				if (empty($cmp_result))
				{
					$cast_arr[$role_id][] = array("cast_id"=>$cast_id,"name_type"=>$this->name_type[$i], "last_name"=>trim($this->name_last[$i]),"first_name"=>trim($this->name_first[$i]), "alphabet"=>$this->alphabet[$i]);
				}
				else
				{
					$cast_arr[$role_id][] = array("cast_id"=>$this->cast_id[$i],"name_type"=>$this->name_type[$i],"last_name"=>trim($this->name_last[$i]),"first_name"=>trim($this->name_first[$i]), "alphabet"=>$this->alphabet[$i]);
				}
			}
			else
			{
				$cast_arr[$role_id][] = array("cast_id"=>$this->cast_id[$i],"name_type"=>$this->name_type[$i],"last_name"=>trim($this->name_last[$i]),"first_name"=>trim($this->name_first[$i]), "alphabet"=>$this->alphabet[$i]);
			}
		}

		return json_encode($cast_arr);
	}
	 */
	private function add_cast_field($cast_id)
	{
		if ($cast_id > 0) {
			$new_cmp_array = array(
				"role_id" => $this->param_role_id, 
				"name_type" => $this->param_name_type,
				"last_name" => $this->param_last_name,
				"first_name" => $this->param_first_name,
				"alphabet" => (int)$this->param_alphabet
			);
		} else {
			$new_cmp_array = false;
		}

		$cast_arr = array();

		// by donald.chen @ 2011-04-08
		foreach ($this->name_type as $role_id => $name_type_arr) {	
			foreach ($name_type_arr as $i => $name_type) {
				if (empty($this->name_first[$role_id][$i])) continue;
		
				$old_cmp_array = array(
					"role_id" => $role_id, 
					"name_type" => $this->name_type[$role_id][$i],
					"last_name" => trim($this->name_last[$role_id][$i]),
					"first_name" => trim($this->name_first[$role_id][$i]), 
					"alphabet" => $this->alphabet[$role_id][$i]
				);
			
				if ($new_cmp_array) {
					$cmp_result = array_diff_assoc($new_cmp_array,$old_cmp_array);
					if (empty($cmp_result)) {
						$cast_arr[$role_id][] = array(
							"cast_id" => $cast_id,
							"name_type" => $this->name_type[$role_id][$i], 
							"last_name" => trim($this->name_last[$role_id][$i]),
							"first_name" => trim($this->name_first[$role_id][$i]), 
							"alphabet" => $this->alphabet[$role_id][$i]
						);
					} else {
						$cast_arr[$role_id][] = array(
							"cast_id" => $this->cast_id[$role_id][$i],
							"name_type" => $this->name_type[$role_id][$i],
							"last_name" => trim($this->name_last[$role_id][$i]),
							"first_name" => trim($this->name_first[$role_id][$i]), 
							"alphabet" => $this->alphabet[$role_id][$i]
						);
					}
				} else {
					$cast_arr[$role_id][] = array(
						"cast_id" => $this->cast_id[$role_id][$i],
						"name_type" => $this->name_type[$role_id][$i],
						"last_name" => trim($this->name_last[$role_id][$i]),
						"first_name" => trim($this->name_first[$role_id][$i]), 
						"alphabet" => $this->alphabet[$role_id][$i]
					);
				}
			}
		}

		return json_encode($cast_arr);
	}

	/**
	 * handle cast main
	 */
	private function handle_cast_main()
	{
		//add
		if ($this->param_cast_id < 0)
		{
			$cast_id = $this->handle_cast();
			if ($cast_id > 0)
			{
				$this->handle_cast_language($cast_id);
			}
			return $cast_id;
		}
		elseif($this->param_cast_id)
		{
			//modify
			//$cast_id = $this->handle_cast();
			//if (false != $cast_id)
			//{
				//$this->handle_cast_language($this->param_cast_id);
			//}
			return $this->param_cast_id;
		}

		return -1;
	}

	/**
	 * operation of cast
	 */
	private function handle_cast()
	{
		$cast = new cast();
		//modify
		if ($this->param_cast_id > 0)
		{
			//$cast = $cast->get($this->param_cast_id);
			//$cast->modified_at = date("Y-m-d H:i:s", $_SERVER['REQUEST_TIME']);
			//$cast->modified_by = CommonUtils::get_user();
		}
		else
		{
			$cast->set($this);
			$cast->created_at = date("Y-m-d H:i:s", $_SERVER['REQUEST_TIME']);
			$cast->created_by = CommonUtils::get_user();
			$cast->modified_at = $cast->created_at;
			$cast->modified_by = $cast->created_by;
			$cast->cast_role_id = $this->param_role_id;
			$cast->programme_id = $this->programme_id;
			$cast->folders = CommonUtils::init_folder("cast", $this);
			$cast->available_tag_types = CommonUtils::get_allow_tags("cast");
			$cast->status = AC::STATUS_NEW;
		}
		
		$cast_id = Model::$dbo['w']->save($cast);
		if ($cast_id >= 0 )
		{
			$this->_log_episode_id = array($this->id);
			$this->_log_programme_id = 0;
			$this->change_log[] = array(
				'type' => 'cast',
				'keys' => array('id'=>$cast_id),
				'is_active'=>1,
				'is_publish'=> 0,
				'episode_id'=>$this->id,
				//for bug:7401    #added by Albie Lu on 2011-10-24
				'programme_id'=>0
			);
			$this->addInfo("cast:".AC::LOG_OP_CREATE.":".$cast_id, "add cast success", json_encode($cast));
			return ($this->param_cast_id > 0) ? true : $cast_id;
		}
		else
		{
			$this->addError("cast:".AC::LOG_OP_CREATE.":".$cast_id, "add cast error", json_encode($cast));
			return false;
		}
	}

	/**
	 * handle cast language
	 */
	private function handle_cast_language($cast_id)
	{
		//$cast_language = new cast_language();
		//$cast_detail = $cast_language->getCastByID($cast_id);
		//record find
		//if ($cast_detail)
		//{
			//$cast_language->delBySql($cast_id);
			//$cast_language_detail = new cast_language();
			//$cast_language_detail->set($cast_detail);
		//}
		//else
		//{
			$cast_language_detail = new cast_language();
		//}
		$lang_code = ($this->param_alphabet == 1) ? AC::LANGUAGE_ZH : AC::LANGUAGE_EN;
		$cast_language_detail->language_id = language::getLanguageID($lang_code);
		$cast_language_detail->cast_id = $cast_id;
		if ($this->param_name_type == 1)
		{
			$cast_language_detail->real_first_name = is_null($this->param_first_name) ? '' : trim($this->param_first_name);
			$cast_language_detail->real_last_name  = is_null($this->param_last_name) ? '' : trim($this->param_last_name);
		}
		elseif ($this->param_name_type == 2)
		{
			$cast_language_detail->first_name = trim($this->param_first_name);
			$cast_language_detail->last_name  = trim($this->param_last_name);
		}
		elseif ($this->param_name_type == 12)
		{
			$cast_language_detail->nickname = is_null($this->param_first_name) ? '' : trim($this->param_first_name);
		}
		elseif ($this->param_name_type == 11)
		{
			$cast_language_detail->other_name = trim($this->param_first_name);
		}
		$ret = Model::$dbo['w']->save($cast_language_detail);
		if ($ret >= 0)
		{
			$this->change_log[] = array(
				'type' => 'cast-language',
				'keys' => array('cast_id'=>$cast_id,'language_id'=>$cast_language_detail->language_id),
				'is_active'=>1,
				'is_publish'=> 0,
				'episode_id'=>$this->id,
			);
			$this->addInfo("cast-language:".AC::LOG_OP_UPDATE.":".$cast_id, "update cast language success", json_encode($cast_language_detail));
		}
		else
		{
			$this->addError("cast-language:".AC::LOG_OP_UPDATE.":".$cast_id, "update cast language error", json_encode($cast_language_detail));
		}
	}

	/**
	 * init page data
	 */
	private function init_page_data()
	{
		$action = new EpisodeGetAction();
		$action->id = $this->id;
		$action->act = 'edit';
		$action->step = 2;
		$action->execute();

		$old_data = $action->getData();
		$this->modified_at = $old_data['episode']->modified_at;
		$new_data['episode'] = Model::diff($old_data['episode'], $this);
		$new_data['episode']->casts = $this->add_cast_field(-1);

		//retain cast/crew list
		$cast_role = new cast_role();
		$cast_role_list = $cast_role->findByInSql($new_data['episode']->highlighted_cast_roles, AC::ROLE_TYPE_CAST);
		//crew role list
		$crew_role_list = $cast_role->findByInSql($new_data['episode']->highlighted_cast_roles, AC::ROLE_TYPE_CREW);

		$cast_role_id = array();
		foreach ($cast_role_list as $cast)
		{
			$cast_role_id[] = $cast->id;
		}

		//crew role list
		$crew_role_id = array();
		foreach ($crew_role_list as $crew)
		{
			$crew_role_id[] = $crew->id;
		}

		//cast list
		$json_cast_list = json_decode($new_data['episode']->casts,true);
		$cast_list = array();
		$crew_list = array();
		if (!empty($json_cast_list))
		{
			foreach ($json_cast_list as $role_id=>$list)
			{
				if (in_array($role_id, $cast_role_id))
				{
					$cast_list[$role_id] = $list;
				}
				elseif (in_array($role_id, $crew_role_id))
				{
					$crew_list[$role_id] = $list;
				}
			}
		}
		else
		{
			$cast_list = array();
			$crew_list = array();
		}
		$old_data['cast_list'] = $cast_list;
		$old_data['crew_list'] = $crew_list;
		if (is_array($this->first_time_onair))
		{
			$this->first_time_onair = implode(' ', $this->first_time_onair);
		}
		$new_data['episode']->first_time_onair = CommonUtils::formatDate($this->first_time_onair);
		if (is_array($this->expire_datetime))
		{
			$this->expire_datetime = implode(' ', $this->expire_datetime);
		}
		$new_data['episode']->expire_datetime  = CommonUtils::formatDate($this->expire_datetime);
		if (is_array($this->publish_datetime))
		{
			$this->publish_datetime = implode(' ', $this->publish_datetime);
		}
		$new_data['episode']->publish_datetime = CommonUtils::formatDate($this->publish_datetime);
		$new_data['episode']->casts = $old_data['episode']->casts;
		
		$new_data['episode']->episode_language[2]->editor_message = $this->editor_message_en;
		
		
		$old_data['episode'] = $new_data['episode'];
		foreach ($old_data as $object=>$data)
		{
			$this->setData($object, $data);
		}

		//jump page
		$this->setData('id', $this->id);
		$this->setData('type', 'episode');
		$this->setData('act', $this->act);
		$this->setData('step', 2);
		$this->setData('from', $this->from);
	}
}
?>
